Using External Entities

To really see how external entities can be put to use, let’s break our employee XML document into multiple pieces.  Our goal is to break the physical structure into manageable chunks, while maintaining the logical structure.

Let’s start with our completed EmployeesWithDTD.xml document.  We are going to break it into three pieces:

EmployeeMaster.xml

This XML document will contain:
the employee content model (DTD) that we have defined,
references to the other employee entities, which in turn will contain individual employee information.

JohnDoe.xml

This is the first employee entity that is referenced by EmployeeMaster.xml.  It contains the content (elements and attributes) for John Doe.  This content already adheres to the DTD defined in the master document.

JaneDoe.xml

This is the second employee entity that is referenced by EmployeeMaster.xml.  It contains the content (elements and attributes) for Jane Doe.  This too adheres to the DTD defined in the master document.

Let’s look at the EmployeeMaster.xml file first.

<?xml version="1.0"?>
<!DOCTYPE employees [
	<!ELEMENT employees ( employee+ )>

	<!ELEMENT employee (name, position, address, phone)>
	<!ATTLIST employee id ID #REQUIRED>

	<!ELEMENT name (first, last)>
	<!ELEMENT first (#PCDATA)>
	<!ELEMENT last  (#PCDATA)>

	<!ELEMENT position (#PCDATA)>

	<!ELEMENT address (street?, city?, state?, zip?)>
	<!ELEMENT street (#PCDATA)>
	<!ELEMENT city   (#PCDATA)>
	<!ELEMENT state  (#PCDATA)>
	<!ELEMENT zip    (#PCDATA)>

	<!ELEMENT phone (main, office*, fax*, mobile*, home*)>
	<!ELEMENT main   (#PCDATA)>
	<!ELEMENT office (#PCDATA)>
	<!ELEMENT fax    (#PCDATA)>
	<!ELEMENT mobile (#PCDATA)>
	<!ELEMENT home   (#PCDATA)>

	<!ENTITY employee1 SYSTEM "JohnDoe.xml">
	<!ENTITY employee2 SYSTEM "JaneDoe.xml">
]>

<employees>

&employee1;
&employee2;

</employees>

File: Chapter 4\EmployeeMaster.xml.

The next two documents contain the data for employees John and Jane Doe.  Their contents is as follows:

<employee id="A1234">
    <name>
        <first>John</first>
        <last>Doe</last>
    </name>
    <position>Programmer</position>
    <address>
        <street>123 Main Street</street>
        <city>Anywhere</city>
        <state>CA</state>
        <zip>92000</zip>
    </address>
    <phone>
        <main>(714) 555-1000</main>
        <fax>(714) 555-1001</fax>
    </phone>
</employee>

File: Chapter 4\JohnDoe.xml.
<employee id="A2345">
    <name>
        <first>Jane</first>
        <last>Doe</last>
    </name>
    <position>Systems Analyst</position>
    <address>
    </address>
    <phone>
        <main>(714) 555-2000</main>
        <mobile>(949) 555-2200</mobile>
        <home>(949) 555-2220</home>
    </phone>
</employee>

File: Chapter 4\JaneDoe.xml

The employee specific files are pretty straightforward.   The master document needs some review, though.  Let’s look at the <!ENTITY> declarations that point to the employee data files.  These are located in the DTD (which makes sense being that the DTD is where they need to be declared).

<!ENTITY employee1 SYSTEM "JohnDoe.xml">
<!ENTITY employee2 SYSTEM "JaneDoe.xml">

The words “employee1” and “employee2” are now system entity references that can be expanded just like character entity references.  The difference is that instead of expanding simple text, the XML processor is going to expand the contents of the external entities (documents).

Let’s see how this is done within the master document.

<employees>
&employee1;
&employee2;
</employees>

Within the root element is expanded the contents of both external entities just as if we were expanding an internal entity.  When we view the EmployeeMaster.xml document in IE5, the logical content model is intact and treated as a single entity, even though it is physically structured as three distinct entities.

File: Chapter 4\EmployeeMaster.xml.